#define _XOPEN_SOURCE
#include <func.h>
#include "head.h"
#include "circleQueue.h"
// #define SALT_LEN 12
// int initDataBase(MYSQL *db);
// int getSalt(char salt[]);
// int usrRegister(MYSQL *db, char* usr_name, char* passwd);
// int usrLogin(MYSQL *db, char* usr_name, char* inputPasswd);  //密码错误返回-1， 正确返回0， 用户不存在返回-2
// int main(){
//     MYSQL *db = mysql_init(NULL);
//     initDataBase(db);
//     usrRegister(db, "usr3", "usr3");
//     int ret = usrLogin(db, "usr1", "123");//-1
//     printf("ret = %d\n", ret);
//     ret = usrLogin(db, "usr1", "usr1");//0
//     printf("ret = %d\n", ret);
//     ret = usrLogin(db, "usr5", "123");//-2
//     printf("ret = %d\n", ret);
//     mysql_close(db);
// }

int initDataBase(MYSQL *db){
    char *host = "localhost";
    char *user = "root";
    char *password = "123456";
    char *database = "Cloud_4";
    MYSQL *ret = mysql_real_connect(db, host, user, password, database, 0, NULL, 0);
    if(ret == NULL){
        printf("Error: %s\n", mysql_error(db));
        exit(-1);
    }
    return 0;
}

int usrRegister(MYSQL *db, char* usr_name, char* passwd){
    char salt[SALT_LEN + 1] = {0};
    getSalt(salt);
    char cryptograph[500] = {0};
    strcpy(cryptograph,crypt(passwd, salt)); //crypt(密码，盐值);
    //insert into UserLoginInformation(user_name, salt, crypt) values(NAME, SALT, CRYPT)
    char sqlCommand[1024] = {0};
    sprintf(sqlCommand, "insert into UserLoginInformation(usr_name, salt, crypt) values('%s', '%s', '%s');", usr_name, salt, cryptograph);
    //puts(sqlCommand);
    int qret = mysql_query(db, sqlCommand);
    if(qret != 0){
        printf("Error: %s\n", mysql_error(db));
        return -1;
    }
    return 0;
}

int usrLogin(MYSQL *db, char* usr_name, char* inputPasswd){
    //select salt, crypt from UserLoginInformation where usr_name = 'usr1';
    char sqlCommand[255] = {0};
    sprintf(sqlCommand, "select salt, crypt from UserLoginInformation where usr_name = '%s';", usr_name);
    int qret = mysql_query(db, sqlCommand);
    if(qret != 0){
        printf("Error: %s\n", mysql_error(db));
        return -1;
    }
    MYSQL_RES *result = mysql_store_result(db);
    char salt[30] = {0};
    char cryptograph[500] = {0};
    MYSQL_ROW row = mysql_fetch_row(result);
    if(row == NULL){
        return 2;
    }
    strcpy(salt, row[0]);
    strcpy(cryptograph, row[1]);
    int ret = strcmp(cryptograph, crypt(inputPasswd, salt));
    mysql_free_result(result);
    if(ret == 0)
        return 0;
    else
        return 1;
}

int insertCatalogWhenRegister(MYSQL *db, char *usr_name){
    //insert into Catalog(file_name, usr_name, pre_id) values('usr3', 'usr3', 0);
    char sqlCommand[255] = {0};
    sprintf(sqlCommand, "insert into Catalog(file_name, usr_name, pre_id) values('/%s', '%s', 0);", usr_name, usr_name);
    int qret = mysql_query(db, sqlCommand);
    if(qret != 0){
        printf("Error: %s\n", mysql_error(db));
        return -1;
    }
    return 0;
}

int insertCatalog(MYSQL *db, char *file_name, char *usr_name, int pre_id, char *md5){
    //insert into Catalog(file_name, usr_name, pre_id, md5) values(File_name, Usr_name, Pre_id, Md5);
    char sqlCommand[255] = {0};
    sprintf(sqlCommand, "insert into Catalog(file_name, usr_name, pre_id, md5) values('%s', '%s', %d, '%s');", file_name, usr_name, pre_id, md5);
    int qret = mysql_query(db, sqlCommand);
    if(qret != 0){
        printf("Error: %s\n", mysql_error(db));
        return -1;
    }
    return 0;
}

int getIdFromFileName(MYSQL *db, char* file_name){//通过file_name获取对应ID
    //select id from Catalog where file_name = '/usr1/dir1'
    char sqlCommand[255] = {0};
    sprintf(sqlCommand, "select id from Catalog where file_name = '%s';", file_name);
    //puts(sqlCommand);
    int qret = mysql_query(db, sqlCommand);
    if(qret != 0){
        printf("Error: %s\n", mysql_error(db));
        return -1;
    }
    MYSQL_RES *result = mysql_store_result(db);
    MYSQL_ROW row = mysql_fetch_row(result);
    int id = atoi(row[0]);
    mysql_free_result(result);
    return id;
}

int getMd5FromFileName(MYSQL *db, char *file_name, char *md5){
    //select md5 from Catalog where file_name = 'file_name'
    char sqlCommand[255] = {0};
    sprintf(sqlCommand, "select md5 from Catalog where file_name = '%s';", file_name);
    //puts(sqlCommand);
    int qret = mysql_query(db, sqlCommand);
    if(qret != 0){
        printf("Error: %s\n", mysql_error(db));
        return -1;
    }
    MYSQL_RES *result = mysql_store_result(db);
    MYSQL_ROW row = mysql_fetch_row(result);
    if(row == NULL){
        return -1;
    }
    strcpy(md5, row[0]);
    //puts(md5);
    mysql_free_result(result);
    return 0;
}

int insertDirToCatalog(MYSQL *db, char *file_name, char *usr_name, int pre_id){
    //insert into Catalog(file_name, usr_name, pre_id, md5) values(File_name, Usr_name, Pre_id, Md5);
    char sqlCommand[255] = {0};
    sprintf(sqlCommand, "insert into Catalog(file_name, usr_name, pre_id) values('%s', '%s', %d);", file_name, usr_name, pre_id);
    int qret = mysql_query(db, sqlCommand);
    if(qret != 0){
        //printf("Error: %s\n", mysql_error(db));
        return -1;
    }
    return 0;
}

int findChildFileAndDirFromPreId(MYSQL *db, int preId, char *arr){
    //select file_name from Catalog where pre_id = xx;
    char sqlCommand[255] = {0};
    sprintf(sqlCommand, "select file_name from Catalog where pre_id = %d;", preId);
    int qret = mysql_query(db, sqlCommand);
    if(qret != 0){
        //printf("Error: %s\n", mysql_error(db));
        return -1;
    }
    MYSQL_RES *result = mysql_store_result(db);
    MYSQL_ROW row = mysql_fetch_row(result);
    //int length = 0;
    char tmp[200] = {0}; 
    char name[50] = {0};
    if(row == NULL){
        return -1;
    }
    else{
        do{
            for(int i = 0; i < mysql_num_fields(result); ++i){
                memset(name, 0, sizeof(name));
                getFileName(name, row[0]);
                strcat(tmp, name);
                strcat(tmp, " ");
            }
        }while((row = mysql_fetch_row(result)) != NULL);
        strcpy(arr, tmp);
    }    
    mysql_free_result(result);
    return 0;
}

int isDirAndIsBlongToUsr(MYSQL *db, char *file_name, char *usr_name){
    //select * from Catalog where file_name = 'file_name' and usr_name = 'usr_name' and md5 is NULL;
    char sqlCommand[255] = {0};
    sprintf(sqlCommand, "select * from Catalog where file_name = '%s' and usr_name = '%s' and md5 is NULL;", file_name, usr_name);
    int qret = mysql_query(db, sqlCommand);
    if(qret != 0){
        printf("Error: %s\n", mysql_error(db));
        return -1;
    }
    MYSQL_RES *result = mysql_store_result(db);
    MYSQL_ROW row = mysql_fetch_row(result);
    if(row == NULL){
        return -1;
    }
    else{
        mysql_free_result(result);
        return 0;
    }
}

int FindFatherPathByChildPath(MYSQL *db, char *child_file_name, char *father_file_name){
    //select pre_id from Catalog where file_name = 'xxx';
    char sqlCommand[255] = {0};
    sprintf(sqlCommand, "select pre_id from Catalog where file_name = '%s';", child_file_name);
    int qret = mysql_query(db, sqlCommand);
    if(qret != 0){
        //printf("Error: %s\n", mysql_error(db));
        return -1;
    }
    MYSQL_RES *result = mysql_store_result(db);
    MYSQL_ROW row = mysql_fetch_row(result);
    if(row == NULL){
        return -1;
    }
    int father_id = atoi(row[0]);
    if(father_id == 0){
        return -1;
    }
    mysql_free_result(result);
    //select file_name from Catalog where id = xxx;
    memset(sqlCommand, 0, sizeof(sqlCommand));
    sprintf(sqlCommand, "select file_name from Catalog where id = %d;", father_id);
    qret = mysql_query(db, sqlCommand);
    if(qret != 0){
        //printf("Error: %s\n", mysql_error(db));
        return -1;
    }
    MYSQL_RES *result2 = mysql_store_result(db);
    MYSQL_ROW row2 = mysql_fetch_row(result2);
    strcpy(father_file_name, row2[0]);
    mysql_free_result(result2);
    return 0;
}

int isFileAndIsBlongToUsr(MYSQL *db, char *file_name, char *usr_name){
    //select * from Catalog where file_name = 'file_name' and usr_name = 'usr_name' and md5 is not NULL;
    char sqlCommand[255] = {0};
    sprintf(sqlCommand, "select * from Catalog where file_name = '%s' and usr_name = '%s' and md5 is not NULL;", file_name, usr_name);
    int qret = mysql_query(db, sqlCommand);
    if(qret != 0){
        printf("Error: %s\n", mysql_error(db));
        return -1;
    }
    MYSQL_RES *result = mysql_store_result(db);
    MYSQL_ROW row = mysql_fetch_row(result);
    if(row == NULL){
        return -1;
    }
    else{
        mysql_free_result(result);
        return 0;
    }
}

int delCatalogByFilename(MYSQL *db, char *file_name){
    //delete from Catalog where file_name = '';
    char sqlCommand[255] = {0};
    sprintf(sqlCommand, "delete from Catalog where file_name = '%s';", file_name);
    int qret = mysql_query(db, sqlCommand);
    //puts(sqlCommand);
    if(qret != 0){
        printf("Error: %s\n", mysql_error(db));
        return -1;
    }
    return 0;
}

int isDirCanDelete(MYSQL *db, char *file_name, char *usr_name){
    //select * from Catalog where file_name = 'file_name' and usr_name = 'usr_name' and md5 is NULL;
    char sqlCommand[255] = {0};
    sprintf(sqlCommand, "select * from Catalog where file_name = '%s' and usr_name = '%s' and md5 is NULL and pre_id <> 0;", file_name, usr_name);
    int qret = mysql_query(db, sqlCommand);
    if(qret != 0){
        printf("Error: %s\n", mysql_error(db));
        return -1;
    }
    MYSQL_RES *result = mysql_store_result(db);
    MYSQL_ROW row = mysql_fetch_row(result);
    if(row == NULL){
        return -1;
    }
    else{
        mysql_free_result(result);
        return 0;
    }
}

int delCatalogById(MYSQL *db, int id){
    //delete from Catalog where id = xx;
    char sqlCommand[255] = {0};
    sprintf(sqlCommand, "delete from Catalog where id = %d;", id);
    int qret = mysql_query(db, sqlCommand);
    //puts(sqlCommand);
    if(qret != 0){
        printf("Error: %s\n", mysql_error(db));
        return -1;
    }
    return 0;
}

int insertTokenToUserInformation(MYSQL *db, char *usr_name, char *token){
    //update UserLoginInformation set token = 'xxx' where usr_name = 'xxx';
    char sqlCommand[255] = {0};
    sprintf(sqlCommand, "update UserLoginInformation set token = '%s' where usr_name = '%s';", token, usr_name);
    int qret = mysql_query(db, sqlCommand);
    //puts(sqlCommand);
    if(qret != 0){
        printf("Error: %s\n", mysql_error(db));
        return -1;
    }
    return 0;
}

int usrRegisterWithToken(MYSQL *db, char* usr_name, char* passwd, char* token){
    char salt[SALT_LEN + 1] = {0};
    getSalt(salt);
    char cryptograph[500] = {0};
    strcpy(cryptograph,crypt(passwd, salt)); //crypt(密码，盐值);
    //insert into UserLoginInformation(user_name, salt, crypt, token) values(NAME, SALT, CRYPT, TOKEN);
    char sqlCommand[1024] = {0};
    sprintf(sqlCommand, "insert into UserLoginInformation(usr_name, salt, crypt, token) values('%s', '%s', '%s', '%s');", usr_name, salt, cryptograph, token);
    //puts(sqlCommand);
    int qret = mysql_query(db, sqlCommand);
    if(qret != 0){
        printf("Error: %s\n", mysql_error(db));
        return -1;
    }
    return 0;
}

int findTokenWithUsrName(MYSQL *db, char* usr_name, char* token){
    //select token from UserLoginInformation where usr_name = 'xxx';
    char sqlCommand[1024] = {0};
    sprintf(sqlCommand, "select token from UserLoginInformation where usr_name = '%s';", usr_name);
    //puts(sqlCommand);
    int qret = mysql_query(db, sqlCommand);
    if(qret != 0){
        printf("Error: %s\n", mysql_error(db));
        return -1;
    }
    MYSQL_RES *result = mysql_store_result(db);
    MYSQL_ROW row = mysql_fetch_row(result);
    if(row == NULL){
        return -1;
    }
    else{
        if(row[0] == NULL){
            return 1;//token为空时返回1
        }
        strcpy(token, row[0]);
        return 0;
    }
}

int setTokenNull(MYSQL *db){
    //update UserLoginInformation set token = NULL;
    char sqlCommand[] = "update UserLoginInformation set token = NULL;";
    int qret = mysql_query(db, sqlCommand);
    if(qret != 0){
        printf("Error: %s\n", mysql_error(db));
        return -1;
    }
    return 0;
}